-------------------------------------------------------------------------------
Sample Name: CDArchive

Description: A simple utility that allows you to scan a CD and archive its 
             contents on an .MDB database for subsequent searches. 

Download URL: http://www.Planet-Source-Code.com/vb/scripts/ShowCode.asp?txtCodeId=21822&lngWId=1

-------------------------------------------------------------------------------

IMPORTANT NOTE
The first step to ensure that you can migrate the VB6 project to VB.NET is 
loading the original project in the Visual Basic 6 IDE, run it to ensure that 
it works fine, that all the required type libraries are installed, and that all 
file paths are correct. 
Regardless of whether you edited the source code in any way, you should save 
the VB6 project: this save operation ensures that the .vbp file includes  
the correct path and version of referenced type libraries. 
After saving the project, it's usually a good idea to compile the VB6 project
to an executable, to detect any VB6 compilation errors that would appear under 
VB.NET as well. 
(If you don't recompile the project VB Migration Partner will display a warning 
when you later load the project.)


A good pratice before migrating a sample is to check whether the application 
uses some external files (images, sounds, databases, INI files, etc.)
It's not necessary to copy those files manually to the migrates solution folder.
VBMP provides a dedicated pragma for this job. This sample uses the 
ARCHIVE.MDB and ARCHIVE.MDB.BAK Access database files, so you can insert
a pragma for doing the copy. Insert these lines at the top of any file of the project:

'##AddDataFile ARCHIVE.MDB
'##AddDataFile ARCHIVE.MDB.BAK

At the first migration attempt, the VB.NET compiler shows two compilation errors.

The first is a typing error in the ListView1.MoveMove event handler code. 
The name of the treeview is not correctly written (cdscds instead of cds). 
You have to simply correct the code manually. When we fix a bug in the original
code, we as a best practice we use a Note pragma to annotate the correction:


Label1.Caption = cow.Tag
If DoesNodeExsist(cow.Key) = True Then 
   '## Note original code had a bug => cdscds.Nodes(cow.key).Expanded = True
   cds.Nodes(cow.key).Expanded = True
		
   cds.Nodes(cow.Key).Selected = True
   On  Error Resume Next 
   If TypeName6(lastnode) = "Nothing" Then  lastnode = cds.Nodes(cow.Key)

   lastnode = cds.Nodes(cow.Key)
   cds.Nodes(cow.Key).EnsureVisible()
End If

The second compilation error is caused by an array used with a non-zero
lower bound, that are not supported by VB.NET. This is the VB6 code line:

	ReDim Preserve DirQUE(LBound(DirQUE) To UBound(DirQUE) + 1)

VB Migration Partner generates the following VB.NET code:

	ReDim Preserve DirQUE(LBound6(DirQUE) To UBound6(DirQUE) + 1)


You can follow either of the following strategies: 

1) Considering that the rest of codes references this array as a standard zero 
   lower bound array, you can simply modify the Redim statement and remove the
   LBound specification.
   Do it editing directly the VB6 source code or use a ReplaceStatement pragma
   that will modify code generated by VBMS, as below:

   '##ReplaceStatement ReDim Preserve DirQUE(UBound6(DirQUE) + 1)   
   ReDim Preserve DirQUE(LBound(DirQUE) To UBound(DirQUE) + 1)   

2) VB Migration Partner provides support for non-zero LBound array trough the 
   VB6Array special class. You can force VB Migration Partner to convert an array 
   as VB6Array by inserting an ArrayBound pragma immediatly before the array 
   declaration, as showed below:

   MODULE1.BAS

   '##DirQUE.ArrayBounds ForceVB6Array
   Public DirQUE() As String
   Public Declare Function SetVolumeLabel Lib "kernel32.dll" Alias "SetVolumeLabelA" (ByVal lpRootPathName As String, ByVal lpVolumeName As String) As Long
   Private Declare Function GetLogicalDriveStrings Lib "kernel32" Alias "GetLogicalDriveStringsA" (ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long
   Private Declare Function GetDrivetype Lib "kernel32" Alias "GetDriveTypeA" (ByVal nDrive As String) As Long
   Public Declare Function GetLogicalDrives Lib "kernel32.dll" () As Long
   Public Declare Function GetVolumeInformation Lib "kernel32.dll" Alias "GetVolumeInformationA" (ByVal lpRootPathName As String, ByVal lpVolumeNameBuffer As String, ByVal nVolumeNameSize As Long, lpVolumeSerialNumber As Long, lpMaximumComponentLength As Long, lpFileSystemFlags As Long, ByVal lpFileSystemNameBuffer As String, ByVal nFileSystemNameSize As Long) As Long
      

Once done, you'll have no more compilation errors. 

The next step for the correct runtime execution of this sample, is using the
UseByVal pragma. As you can read in the documentation, 
When a read-only property is used as an argument to a method, VB6 
passes the propertys value using by-value semantics, regardless of 
whether the receiving parameter is declared with the ByRef keyword. 
Under the same circumstances, however, VB.NET passes the propertys value 
using by-reference semantics. This detail can cause a runtime exception when 
the property is one of those exposed by the Connection, Recordset, and other 
ADODB objects.

In this specific sample, the GetDir and makesize methods have the abovementioned
problem. You can fix both problems by adding a UseByVal pragma at the top of 
any source file in the project, for example in Module1.Bas:

'##project:UseByVal Yes


At last, you have to add two UseSystemString pragmas to correctly pass a 
structure to the FindFirstFile/FindNextFile Windows API methods.

In Module1.bas:


Public Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" (ByVal lpFileName As String, _
       lpFindFileData As WIN32_FIND_DATA) As Long
Public Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA" (ByVal hFindFile As Long, _
       lpFindFileData As WIN32_FIND_DATA) As Long
Public Type FILETIME
        dwLowDateTime As Long
        dwHighDateTime As Long
End Type
Public Type WIN32_FIND_DATA
        dwFileAttributes As Long
        ftCreationTime As FILETIME
        ftLastAccessTime As FILETIME
        ftLastWriteTime As FILETIME
        nFileSizeHigh As Long
        nFileSizeLow As Long
        dwReserved0 As Long
        dwReserved1 As Long
        '##cFileName.UseSystemString True
        cFileName As String * 260
        '##cAlternate.UseSystemString True	
        cAlternate As String * 14
End Type


That's all. Now the VB.NET code compiles and executes correctly.
